﻿#include "function_dl_3.h"
Detection_dl_3::Detection_dl_3(QDialog* parent, QSettings* qsettings, QString section) : QDialog(parent)
{
    m_qsettings = qsettings;
    m_section = section;

    //m_model_image_path = QCoreApplication::applicationDirPath() + "/" + m_model_image_path;

    this->setWindowTitle(("AI检测"));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);



    m_view = new MyQGraphicsView(this);
    m_view->setGeometry(660 * ratio_x, 0, 1000 * 1.25 * ratio_x, 800 * 1.25 * ratio_y);
    //m_view->m_graphics_shape_rect = new GraphicsShapeRect(100,100,100,100);
    //m_view->m_scene->addItem(m_view->m_graphics_shape_rect);
    /*QRectF qrectf = m_view->m_graphics_shape_rect->boundingRect();
    row1 = (int)qrectf.y();
    column1 = (int)qrectf.x();
    row2 = (int)(qrectf.y() + qrectf.height());
    column2 = (int)(qrectf.x() + qrectf.width());
    connect(m_view->m_graphics_shape_rect, &GraphicsShapeRect::sendMessage, m_view->m_pixmapItem, &MyQGraphicsPixmapItem::receiveMessage);*/

    QSize control_size(120*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index = 0;

    QSize ButtonSize(160 * ratio_x, 40 * ratio_y);
    m_pushbutton_open_model = new QPushButton();
        m_pushbutton_open_model->setFixedSize(control_size);
        m_pushbutton_open_model->setText("设置模型地址");
        connect(m_pushbutton_open_model, &QPushButton::clicked, this, [=]() {
            QString filename;
            filename = QFileDialog::getOpenFileName(this,
                tr("选择模型"),
                "",
                tr("(*.proj)"));
//                tr("(*.a *.b)"));
            if (filename.isEmpty())
            {
                return;
            }
            RetrainedModelFileName = filename;
            m_qlabel_model_path->setText(RetrainedModelFileName);

//            m_dl.unload();
//            m_dl.load((char*)filename.toLocal8Bit().toStdString().c_str(), (char*)"passward", m_detection_segment);

        });

        qgridLayout->addWidget(m_pushbutton_open_model, index, 0);


        m_qlabel_model_path = new QLabel();
        m_qlabel_model_path->setText("");
        m_qlabel_model_path->setFixedSize(500 * ratio_x, 40 * ratio_y);
        qgridLayout->addWidget(m_qlabel_model_path, index, 1);
        index++;

//        m_qlabel_detection_segment = new QLabel();
//        m_qlabel_detection_segment->setText("检测方法");
//        m_qlabel_detection_segment->setFixedSize(500 * ratio_x, 40 * ratio_y);
//        qgridLayout->addWidget(m_qlabel_detection_segment, index, 0);


//		m_qcombobox_detection_segment = new QComboBox(this);
//		m_qcombobox_detection_segment->setFixedSize(control_size);
//		m_qcombobox_detection_segment->addItem("目标检测");
//		m_qcombobox_detection_segment->addItem("实例分割");
//		qgridLayout->addWidget(m_qcombobox_detection_segment, index, 1);
//        index++;

      /*  m_qlabel_threshold_size = new QLabel();
        m_qlabel_threshold_size->setText("缺陷面积阈值");
        m_qlabel_threshold_size->setFixedSize(control_size);
        qgridLayout->addWidget(m_qlabel_threshold_size,index,0);
        m_qspinbox_threshold_size = new QSpinBox();
        m_qspinbox_threshold_size->setFixedSize(control_size);
        m_qspinbox_threshold_size->setMinimum(0);
        m_qspinbox_threshold_size->setMaximum(10000);
        qgridLayout->addWidget(m_qspinbox_threshold_size,index,1);
        index++;


        m_qlabel_threshold_score = new QLabel();
        m_qlabel_threshold_score->setText("缺陷分数阈值");
        m_qlabel_threshold_score->setFixedSize(control_size);
        qgridLayout->addWidget(m_qlabel_threshold_score,index,0);
        m_qdoublespinbox_threshold_score = new QDoubleSpinBox();
        m_qdoublespinbox_threshold_score->setFixedSize(control_size);
        m_qdoublespinbox_threshold_score->setMinimum(0);
        m_qdoublespinbox_threshold_score->setMaximum(1);
        qgridLayout->addWidget(m_qdoublespinbox_threshold_score,index,1);
        index++;*/


    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("保存参数");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &Detection_dl_3::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);
    index++;

    m_pushbutton_show_orign_image = new QPushButton(this);
    m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("显示原图");
    connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this,[=]() {
        QImage q_image = matToQImage(m_image);
        m_view->setImage(q_image,"");
        return true;
    });
    qgridLayout->addWidget(m_pushbutton_show_orign_image, index,0);

    m_pushbutton_detection = new QPushButton(this);
    m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("检测");
    connect(m_pushbutton_detection, &QPushButton::clicked, this, &Detection_dl_3::detectionImage);
    qgridLayout->addWidget(m_pushbutton_detection, index,1);
    index++;

    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("退出");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });
	index++;
    

    m_qwidget_tableview = new  QWidgetTableView(nullptr,m_section);
	m_qwidget_tableview->setFixedSize(600, 300);

    qgridLayout->addWidget(m_qwidget_tableview, index, 0);

    loadParameter();

}

Detection_dl_3::~Detection_dl_3()
{
    ;
}


int Detection_dl_3::detection(Mat image, QString& message)
{
    m_image = image;
    if(image.empty())
    {
        message = "检测图像为空 ";
        return -1;
    }

    /*if(image.channels()==1)
    {
        cvtColor(image,image,COLOR_GRAY2BGR);
    }*/

    if(m_state==false)
    {
        return 0;
    }


    vector<vector<DefectResult>> result_all;
    m_dl->predictImage(image,result_all);

	result_defect.clear();

	if (result_all.size() == 0)
	{
		message = "OK";
		return 1;
	}
	///第一步遍历一遍所有缺陷，找到未知的缺陷

	for (auto& obj : result_all[0]) {
		int standard_index = -1;
		for (auto& obj_standard : m_vector_defect_standard)
		{
			
			if (obj.name == obj_standard.name)
			{
				standard_index = 0;
				if (obj.threshold_score < obj_standard.threshold_score)
				{
					break;
				}
				if (obj.width < obj_standard.threshold_width && obj.height < obj_standard.threshold_height && obj.area < obj_standard.threshold_size)
				{
					break;
				}
			
				result_defect.push_back(obj);
				message += QString::fromStdString(obj.name) + ":宽度" + QString::number(obj.width) + ":高度" + QString::number(obj.height) + ":面积" + QString::number(obj.area) + "分数" + QString::number(obj.threshold_score) + "\n";
				break;
			}
		}	
		if (standard_index == -1)
		{
			result_defect.push_back(obj);
			message += QString::fromStdString(obj.name) + ":宽度" + QString::number(obj.width) + ":高度" + QString::number(obj.height) + ":面积" + QString::number(obj.area) + "分数" + QString::number(obj.threshold_score) + "\n";
		}
	}
	
	

	if (result_defect.size() > 0)
	{
		return 0;
	}
  
	message = "OK";
    return 1;

}

void Detection_dl_3::detectionImage()
{
    if(m_image.empty())
       {
           QMessageBox::information(nullptr,"","没有图像");
           return;
       }

       QString message;


       bool state = detection(m_image, message);



       Mat image_show;

       draw(m_image,image_show);

       QImage q_image = matToQImage(image_show);
       if (!q_image.isNull())
       {
           m_view->setImage(q_image, message);
       }

}

void Detection_dl_3::draw(Mat image_in, Mat& image_out)
{
	image_out = image_in.clone();
	for (auto obj : result_defect)
	{
		drawContours(image_out, obj.contour, -1, Scalar(0, 0, 255), -1);
	}
    result_defect.clear();
}

void Detection_dl_3::loadParameter()
{
    try
    {
        RetrainedModelFileName = m_qsettings->value(m_section + "/" + "RetrainedModelFileName","").toString();
       /* ThresholdSize = m_qsettings->value(m_section + "/" + "ThresholdSize", 100).toInt();
        ThresholdScore= m_qsettings->value(m_section + "/" + "ThresholdScore", 0.5).toDouble();*/
//        m_detection_segment = m_qsettings->value(m_section + "/" + "m_detection_segment", 0).toInt();



        m_qlabel_model_path->setText(RetrainedModelFileName);
       /* m_qspinbox_threshold_size->setValue(ThresholdSize);
        m_qdoublespinbox_threshold_score->setValue(ThresholdScore);*/
//		m_qcombobox_detection_segment->setCurrentIndex(m_detection_segment);
		save_detection_standard_widgrt(m_qwidget_tableview, m_vector_defect_standard);
    }
    catch(exception& error)
    {
        QMessageBox::critical(nullptr,error.what() , m_section + "参数需要重新设置");
    }




   /* if(state == false)
        QMessageBox::critical(nullptr,"", m_section + "加载模型失败");*/
    return ;
}

void Detection_dl_3::saveParameter()
{
    try
        {
            RetrainedModelFileName = m_qlabel_model_path->text();
          /*  ThresholdSize = m_qspinbox_threshold_size->value();
            ThresholdScore=m_qdoublespinbox_threshold_score->value();*/
//			m_detection_segment = m_qcombobox_detection_segment->currentIndex();

            m_qsettings->setValue(m_section + "/" + "RetrainedModelFileName", RetrainedModelFileName);
           /* m_qsettings->setValue(m_section + "/" + "ThresholdSize", ThresholdSize);
            m_qsettings->setValue(m_section + "/" + "ThresholdScore", ThresholdScore);*/
//			m_qsettings->setValue(m_section + "/" + "m_detection_segment", m_detection_segment);
			
			save_detection_standard_widgrt(m_qwidget_tableview, m_vector_defect_standard);
        }
        catch(exception& error)
        {
            QMessageBox::critical(nullptr,error.what() , m_section + "参数需要重新设置");
        }
    


}

bool Detection_dl_3::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image,"");
    return true;
}

void Detection_dl_3::loadmodel()
{



    m_dl = new AIDll();
    string message;
    string para_path  = RetrainedModelFileName.toLocal8Bit().toStdString();
    QString name = "缺陷检测";
    vector<string> m_vector_node;
    m_vector_node.push_back(name.toLocal8Bit().toStdString());


    if(false == m_dl->loadPorjectFiles(para_path,m_vector_node, 1000, 1000, 3,message))
    {
        ;
    }
//        QMessageBox::information(nullptr,"ai", QString::fromStdString(message));
	else
	{
		vector_dl_3.push_back(m_dl);
		m_state = true;
	}
	
}

void Detection_dl_3::save_detection_standard_widgrt(QWidgetTableView* roi_sqllite, vector<DefectStandard>& vector_defect_standard)
{
	roi_sqllite->submit();
	vector_defect_standard.clear();
    for (int j = 0; j < roi_sqllite->m_qsltablemodel->rowCount(); j++)
	{
		DefectStandard defect_standard;
        defect_standard.name = roi_sqllite->m_qsltablemodel->data(roi_sqllite->m_qsltablemodel->index(j, 1)).toString().toStdString();
        defect_standard.threshold_score = roi_sqllite->m_qsltablemodel->data(roi_sqllite->m_qsltablemodel->index(j, 2)).toDouble();
		defect_standard.threshold_width = roi_sqllite->m_qsltablemodel->data(roi_sqllite->m_qsltablemodel->index(j, 3)).toDouble();
		defect_standard.threshold_height = roi_sqllite->m_qsltablemodel->data(roi_sqllite->m_qsltablemodel->index(j, 4)).toDouble();
        defect_standard.threshold_size = roi_sqllite->m_qsltablemodel->data(roi_sqllite->m_qsltablemodel->index(j, 5)).toDouble();
		vector_defect_standard.push_back(defect_standard);
	}
}
